package com.ruoyi.web.controller.erpbase;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.enums.SaleOrPurchType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.flowable.service.IFlowDefinitionService;
import com.ruoyi.flowable.service.IFlowTaskService;
import com.ruoyi.system.domain.ApprovalConfig;
import com.ruoyi.system.domain.ExportParam;
import com.ruoyi.system.domain.FlowProcDefDto;
import com.ruoyi.system.domain.SalePlan;
import com.ruoyi.system.service.IApprovalConfigService;
import com.ruoyi.system.service.ISalePlanService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 采购计划Controller
 * 
 * @author he
 * @date 2025-08-14
 */
@Api(tags = "采购计划接口")
@RestController
@RequestMapping("/system/purchPlan")
public class PurchPlanController extends BaseController
{
    @Autowired
    private ISalePlanService salePlanService;

    @Autowired
    private IFlowDefinitionService flowDefinitionService;

    @Autowired
    private IFlowTaskService flowTaskService;

    @Autowired
    private IApprovalConfigService approvalConfigService;

    /**
     * 查询采购计划列表
     */
    @ApiOperation("查询采购计划信息")
    @PreAuthorize("@ss.hasPermi('system:purchPlan:list')")
    @GetMapping("/list")
    public TableDataInfo list(SalePlan salePlan)
    {
        startPage();
        salePlan.setType(Long.valueOf(SaleOrPurchType.PURCH.getCode()));
        List<SalePlan> list = salePlanService.selectSalePlanList(salePlan);
        return getDataTable(list);
    }

    /**
     * 导出采购计划列表
     */
    @ApiOperation("导出采购计划信息")
    @PreAuthorize("@ss.hasPermi('system:purchPlan:export')")
    @Log(title = "采购计划", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, SalePlan salePlan)
    {
        salePlan.setType(Long.valueOf(SaleOrPurchType.PURCH.getCode()));
        List<SalePlan> list = salePlanService.selectSalePlanList(salePlan);
        ExcelUtil<SalePlan> util = new ExcelUtil<SalePlan>(SalePlan.class);
        util.exportExcel(response, list, "采购计划数据");
    }

    /**
     * 获取采购计划详细信息
     */
    @ApiOperation("获取采购计划详细信息")
    @PreAuthorize("@ss.hasPermi('system:purchPlan:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return success(salePlanService.selectSalePlanById(id));
    }

    /**
     * 新增采购计划
     */
    @ApiOperation("新增采购计划信息")
    @PreAuthorize("@ss.hasPermi('system:purchPlan:add')")
    @Log(title = "采购计划", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody SalePlan salePlan)
    {
        salePlan.setType(Long.valueOf(SaleOrPurchType.PURCH.getCode()));
        return toAjax(salePlanService.insertSalePlan(salePlan));
    }

    /**
     * 修改采购计划
     */
    @ApiOperation("修改采购计划信息")
    @PreAuthorize("@ss.hasPermi('system:purchPlan:edit')")
    @Log(title = "采购计划", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody SalePlan salePlan)
    {
        salePlan.setType(Long.valueOf(SaleOrPurchType.PURCH.getCode()));
        salePlan.setUpdateTime(DateUtils.getNowDate());
        salePlan.setUpdateUserId(ObjectUtils.isNotEmpty(SecurityUtils.getUserId()) ? SecurityUtils.getUserId() : 1);
        salePlan.setUpdateUserName(StringUtils.isNotEmpty(SecurityUtils.getUsername()) ? SecurityUtils.getUsername() : "admin");
        return toAjax(salePlanService.updateSalePlan(salePlan));
    }

    /**
     * 删除采购计划
     */
    @ApiOperation("删除采购计划信息")
    @PreAuthorize("@ss.hasPermi('system:purchPlan:remove')")
    @Log(title = "采购计划", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        return toAjax(salePlanService.deleteSalePlanByIds(ids));
    }

    /**
     * 批量发起采购计划审批
     *
     * 需要配置:
     * 1. 画流程图，包括开始节点、用户任务、互斥节点、结束节点
     * 2. 配置表单，展示流程中变量数据
     * 3. 流程保存，将表单配置到流程上
     */
    @ApiOperation("批量发起采购计划审批")
    @Log(title = "采购计划", businessType = BusinessType.UPDATE)
    @PostMapping("/approvalStart")
    public AjaxResult approvalStart(@RequestBody List<Long> ids)
    {
        // 检查是否启用审批流
        if (!approvalConfigService.isModuleEnabled("purch_plan")) {
            return error("采购计划模块未启用审批流，请先在审批配置中启用");
        }

        // 获取流程名称
        ApprovalConfig config = approvalConfigService.selectByModuleCode("purch_plan");
        String flowName = config != null && StringUtils.isNotEmpty(config.getFlowName()) 
                ? config.getFlowName() : "采购计划审核";

        SalePlan queryParam = new SalePlan();
        queryParam.setType(Long.valueOf(SaleOrPurchType.PURCH.getCode()));
        List<SalePlan> allPlans = salePlanService.selectSalePlanList(queryParam);
        
        // 筛选出需要审批的计划
        List<SalePlan> plansToApprove = new ArrayList<>();
        for (SalePlan plan : allPlans) {
            if (ids.contains(plan.getId())) {
                // 检查状态:
                // - 未审批(0)或审批拒绝(3)的可以发起审批
                // - 审批中(1)或已通过(2)的不能重复发起
                if (plan.getCheckState() == null || 
                    plan.getCheckState().longValue() == SaleOrPurchType.APPROVAL_NO.getCode() ||
                    plan.getCheckState() == 0) {
                    plansToApprove.add(plan);
                }
            }
        }
        
        if (plansToApprove.isEmpty()) {
            return error("没有可以发起审批的计划，请检查选中的计划状态");
        }

        if (CollectionUtils.isNotEmpty(plansToApprove)) {
            // 根据流程名称查找流程
            Page<FlowProcDefDto> name = flowDefinitionService.list(flowName, 1, 10);
            List<FlowProcDefDto> records = name.getRecords();
            
            if (CollectionUtils.isEmpty(records)) {
                return error("未找到'" + flowName + "'流程定义，请先配置审批流程");
            }
            
            FlowProcDefDto flowProcDefDto = records.get(0);
            String deploymentId = flowProcDefDto.getDeploymentId();
            String flowId = flowProcDefDto.getId();
            AjaxResult ajaxResult1 = flowTaskService.flowFormData(deploymentId);

            Map<String, Object> variables = new HashMap<>();
            Object o = ajaxResult1.get("data");
            variables.put("formJson", o);

            List<Long> idsToUpdate = new ArrayList<>();
            for (SalePlan plan : plansToApprove) {
                variables.put("id", plan.getId());
                variables.put("planNumber", plan.getNumber());
                variables.put("planName", plan.getName());
                variables.put("sendoutCompany", plan.getSendoutCompany());
                variables.put("receiveCompany", plan.getReceiveCompany());
                variables.put("itemName", plan.getItemName());
                variables.put("total", plan.getTotal());
                
                AjaxResult ajaxResult = flowDefinitionService.startProcessInstanceById(flowId, variables);
                if (ajaxResult.isSuccess()) {
                    idsToUpdate.add(plan.getId());
                }
            }

            if (CollectionUtils.isNotEmpty(idsToUpdate)) {
                salePlanService.updateApprovalState(idsToUpdate, SaleOrPurchType.APPROVAL_YN.getCode());
            }
        }

        return success("成功发起" + plansToApprove.size() + "条审批流程");
    }

    /**
     * 审批流结束触发审核完成
     * 
     * @param approvalResult 包含id和审批结果的对象 {"id": 1, "approved": true/false}
     */
    @ApiOperation("采购计划审批完成回调")
    @Log(title = "采购计划", businessType = BusinessType.UPDATE)
    @PostMapping("/approvalEnd")
    public AjaxResult approvalEnd(@RequestBody Map<String, Object> approvalResult)
    {
        Long id = Long.valueOf(approvalResult.get("id").toString());
        Boolean approved = (Boolean) approvalResult.get("approved");
        
        // 根据审批结果设置不同的状态
        // approved=true: 审批通过(2), approved=false: 审批拒绝(3)
        Integer newState = approved ? SaleOrPurchType.APPROVAL_YES.getCode() : SaleOrPurchType.APPROVAL_NO.getCode();
        salePlanService.updateApprovalState(Arrays.asList(id), newState);
        
        return toAjax(1);
    }

}
